function face_recognition_functions(action, varargin)
    %% FACE_RECOGNITION_FUNCTIONS 人脸识别功能函数集
    % 此文件包含所有与人脸识别相关的功能函数
    %
    % 参数:
    %   action - 要执行的操作名称
    %   varargin - 可变参数，根据不同的操作需要不同的参数
    
    switch action
        case 'selectImage'
            selectImage(varargin{:});
        case 'clearImage'
            clearImage(varargin{:});
        case 'startRecognition'
            startRecognition(varargin{:});
        % 新增图像处理功能
        case 'rotateImage'
            rotateImage(varargin{:});
        case 'cropImage'
            cropImage(varargin{:});
        case 'flipImageH'
            flipImageH(varargin{:});
        case 'flipImageV'
            flipImageV(varargin{:});
        case 'resetImage'
            resetImage(varargin{:});
        case 'convertToGrayscale'
            convertToGrayscale(varargin{:});
        case 'histogramEqualization'
            histogramEqualization(varargin{:});
        % 新增实时更新文本功能
        case 'updateRotationText'
            updateRotationText(varargin{:});
        case 'updateCropText'
            updateCropText(varargin{:});
        % 新增实时摄像头功能
        case 'startCamera'
            startCamera(varargin{:});
        case 'stopCamera'
            stopCamera(varargin{:});
        case 'captureFromCamera'
            captureFromCamera(varargin{:});
        otherwise
            error('未知操作: %s', action);
    end
end

%% --- 图像选择与清除函数 ---

% 选择图像函数
% 功能：打开文件选择对话框，读取并显示选中的图像
% 参数：
%   mainFig: 主窗口句柄
%   originalImgAxes: 原始图像显示区域句柄
%   processedImgAxes: 处理后图像显示区域句柄
function selectImage(mainFig, originalImgAxes, processedImgAxes)
    [filename, pathname] = uigetfile({'*.jpg;*.jpeg;*.png;*.bmp', '图像文件 (*.jpg, *.jpeg, *.png, *.bmp)'}, '选择待识别图像');
    if isequal(filename, 0) || isequal(pathname, 0)
        return;
    end
    
    % 读取图像
    img = imread(fullfile(pathname, filename));
    userData = getappdata(mainFig, 'UserData');
    userData.originalImg = img;
    userData.processedImg = img;
    % 添加一个新字段保存真正的原始图像
    userData.trueOriginalImg = img;
    % 添加灰度化状态标志，初始为false
    userData.isGrayscale = false;
    setappdata(mainFig, 'UserData', userData);
     
    % 显示原始图像
    axes(originalImgAxes);
    imshow(img);
    title('原始图像', 'Color', [1, 1, 1]);
    
    % 显示处理后图像
    axes(processedImgAxes);
    imshow(img);
    title('待识别图像', 'Color', [1, 1, 1]);
    
    % 重置滑动条
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    cropSlider = findobj(mainFig, 'Style', 'slider', 'Min', 0.1);
    rotationText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*°'));
    cropText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*%'));
    
    if ~isempty(rotationSlider) && ~isempty(cropSlider)
        set(rotationSlider, 'Value', 0);
        set(cropSlider, 'Value', 1);
        set(rotationText, 'String', '0°');
        set(cropText, 'String', '100%');
    end
end

% 清除图像函数
% 功能：清除当前显示的图像，重置所有参数
% 参数：
%   mainFig: 主窗口句柄
%   originalImgAxes: 原始图像显示区域句柄
%   processedImgAxes: 处理后图像显示区域句柄
function clearImage(mainFig, originalImgAxes, processedImgAxes)
    userData = getappdata(mainFig, 'UserData');
    userData.originalImg = [];
    userData.processedImg = [];
    % 同时清除真正的原始图像
    userData.trueOriginalImg = [];
    % 重置灰度化状态
    userData.isGrayscale = false;
    setappdata(mainFig, 'UserData', userData);
    
    % 清除原始图像显示
    axes(originalImgAxes);
    cla;
    axis off;
    text(0.5, 0.5, '请选择待识别图像', ...
         'HorizontalAlignment', 'center', ...
         'Color', [0.7, 0.7, 0.7]);
         
    % 清除处理后图像显示
    axes(processedImgAxes);
    cla;
    axis off;
    text(0.5, 0.5, '处理后图像将显示在此', ...
         'HorizontalAlignment', 'center', ...
         'Color', [0.7, 0.7, 0.7]);
end

% 开始识别函数
% 功能：执行人脸识别算法并显示结果
% 参数：
%   mainFig: 主窗口句柄
%   resultText: 结果文本区域句柄
%   similarityText: 相似度显示句柄
%   matchAxes: 匹配图像显示区句柄
function startRecognition(mainFig, resultText, similarityText, matchAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.processedImg)
        msgbox('请先选择待识别图像', '提示', 'warn');
        return;
    end
    
    % 这里应该实现人脸识别算法
    % 由于人脸识别算法较为复杂，此处仅作为示例
    % 实际应用中需要替换为真实的人脸识别代码
    
    % 模拟识别过程
    set(resultText, 'String', '正在识别...');
    pause(1);
    
    % 模拟识别结果
    set(resultText, 'String', '识别完成!');
    set(similarityText, 'String', sprintf('相似度: %.2f%%', rand()*100));
    
    % 显示模拟的匹配结果
    axes(matchAxes);
    % 这里应该显示数据库中匹配到的人脸图像
    % 此处仅作为示例，显示处理后的图像
    imshow(userData.processedImg);
    title('最佳匹配', 'Color', [1, 1, 1]);
end

%% --- 图像处理函数 ---

% 旋转图像函数
% 功能：根据滑动条值旋转图像
% 参数：
%   mainFig: 主窗口句柄
%   imgAxes: 图像显示区域句柄
%   slider: 旋转角度滑动条句柄
function rotateImage(mainFig, imgAxes, slider)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.originalImg)
        warndlg('请先选择图像！', '提示');
        return;
    end
    
    % 获取旋转角度
    angle = get(slider, 'Value');
    
    % 旋转图像
    rotatedImg = imrotate(userData.originalImg, angle, 'bilinear', 'crop');
    
    % 更新处理后图像
    userData.processedImg = rotatedImg;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示旋转后的图像
    axes(imgAxes);
    imshow(rotatedImg);
    title('处理后图像', 'Color', [1, 1, 1]);
end

% 裁切图像函数
% 功能：根据滑动条值裁切图像
% 参数：
%   mainFig: 主窗口句柄
%   imgAxes: 图像显示区域句柄
%   slider: 裁切比例滑动条句柄
function cropImage(mainFig, imgAxes, slider)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.originalImg)
        return;
    end
    
    % 获取裁切比例
    cropRatio = get(slider, 'Value');
    
    % 更新裁切比例显示文本
    cropText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*%'));
    set(cropText, 'String', sprintf('%.0f%%', cropRatio*100));
    
    % 先获取旋转角度
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    angle = get(rotationSlider, 'Value');
    
    % 先旋转原始图像
    rotatedImg = imrotate(userData.originalImg, angle, 'bilinear', 'crop');
    
    % 应用裁切 - 修改为基于旋转后的图像裁切
    [rows, cols, ~] = size(rotatedImg);
    centerRow = round(rows/2);
    centerCol = round(cols/2);
    
    newRows = round(rows * cropRatio);
    newCols = round(cols * cropRatio);
    
    rowStart = max(1, centerRow - round(newRows/2));
    rowEnd = min(rows, rowStart + newRows - 1);
    colStart = max(1, centerCol - round(newCols/2));
    colEnd = min(cols, colStart + newCols - 1);
    
    processedImg = rotatedImg(rowStart:rowEnd, colStart:colEnd, :);
    
    % 如果当前是灰度化状态，则将处理后的图像转换为灰度图
    if isfield(userData, 'isGrayscale') && userData.isGrayscale
        processedImg = rgb2gray(processedImg);
    end
    
    userData.processedImg = processedImg;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示处理后的图像
    axes(imgAxes);
    imshow(processedImg);
    title('处理后图像', 'Color', [1, 1, 1]);
end

% 水平翻转图像函数
function flipImageH(mainFig, imgAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.originalImg)
        return;
    end
    
    % 应用水平翻转到原始图像
    flippedImg = fliplr(userData.originalImg);
    userData.originalImg = flippedImg;
    setappdata(mainFig, 'UserData', userData);
    
    % 重新应用旋转和裁切
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    
    % 直接调用旋转函数来更新处理后的图像
    if ~isempty(rotationSlider)
        rotateImage(mainFig, imgAxes, rotationSlider);
    else
        % 如果找不到滑动条，直接更新显示
        userData.processedImg = userData.originalImg;
        
        % 如果当前是灰度化状态，则将处理后的图像转换为灰度图
        if isfield(userData, 'isGrayscale') && userData.isGrayscale
            userData.processedImg = rgb2gray(userData.processedImg);
        end
        
        setappdata(mainFig, 'UserData', userData);
        axes(imgAxes);
        imshow(userData.processedImg);
        title('处理后图像', 'Color', [1, 1, 1]);
    end
end

% 垂直翻转图像函数
function flipImageV(mainFig, imgAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.originalImg)
        return;
    end
    
    % 应用垂直翻转到原始图像
    flippedImg = flipud(userData.originalImg);
    userData.originalImg = flippedImg;
    setappdata(mainFig, 'UserData', userData);
    
    % 重新应用旋转和裁切
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    
    % 直接调用旋转函数来更新处理后的图像
    if ~isempty(rotationSlider)
        rotateImage(mainFig, imgAxes, rotationSlider);
    else
        % 如果找不到滑动条，直接更新显示
        userData.processedImg = userData.originalImg;
        
        % 如果当前是灰度化状态，则将处理后的图像转换为灰度图
        if isfield(userData, 'isGrayscale') && userData.isGrayscale
            userData.processedImg = rgb2gray(userData.processedImg);
        end
        
        setappdata(mainFig, 'UserData', userData);
        axes(imgAxes);
        imshow(userData.processedImg);
        title('处理后图像', 'Color', [1, 1, 1]);
    end
end

% 新增：实时更新旋转角度文本 - 修复：直接使用传入的文本控件
function updateRotationText(mainFig, rotationText, slider)
    angle = get(slider, 'Value');
    set(rotationText, 'String', sprintf('%.1f°', angle));
end

% 新增：实时更新裁切比例文本 - 修复：直接使用传入的文本控件
function updateCropText(mainFig, cropText, slider)
    cropRatio = get(slider, 'Value');
    set(cropText, 'String', sprintf('%.0f%%', cropRatio*100));
end

% 重置图像函数
% 功能：将处理后的图像重置为原始图像
% 参数：
%   mainFig: 主窗口句柄
%   imgAxes: 图像显示区域句柄
function resetImage(mainFig, imgAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.trueOriginalImg)
        warndlg('请先选择图像！', '提示');
        return;
    end
    
    % 重置图像数据
    userData.originalImg = userData.trueOriginalImg;
    userData.processedImg = userData.trueOriginalImg;
    userData.isGrayscale = false;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示重置后的图像
    axes(imgAxes);
    imshow(userData.trueOriginalImg);
    title('处理后图像', 'Color', [1, 1, 1]);
    
    % 重置滑动条
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    cropSlider = findobj(mainFig, 'Style', 'slider', 'Min', 0.1);
    rotationText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*°'));
    cropText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*%'));
    
    if ~isempty(rotationSlider) && ~isempty(cropSlider)
        set(rotationSlider, 'Value', 0);
        set(cropSlider, 'Value', 1);
        set(rotationText, 'String', '0°');
        set(cropText, 'String', '100%');
    end
end

% 灰度化处理函数 - 修改以设置灰度化状态
function convertToGrayscale(mainFig, imgAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.processedImg)
        msgbox('请先选择待处理的图像', '提示', 'warn');
        return;
    end
    
    % 将图像转换为灰度图
    grayImg = rgb2gray(userData.processedImg);
    userData.processedImg = grayImg;
    % 设置灰度化状态为true
    userData.isGrayscale = true;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示灰度图
    axes(imgAxes);
    imshow(grayImg);
    title('处理后图像', 'Color', [1, 1, 1]);
end

% 直方均衡化函数
% 功能：对图像进行直方均衡化处理，增强对比度
% 参数：
%   mainFig: 主窗口句柄
%   imgAxes: 图像显示区域句柄
function histogramEqualization(mainFig, imgAxes)
    userData = getappdata(mainFig, 'UserData');
    if isempty(userData.processedImg)
        warndlg('请先选择图像！', '提示');
        return;
    end
    
    % 获取当前处理后的图像
    img = userData.processedImg;
    
    % 根据图像类型进行直方均衡化
    if size(img, 3) == 3  % 彩色图像
        % 转换到HSV空间
        hsvImg = rgb2hsv(img);
        % 只对亮度通道进行均衡化
        hsvImg(:,:,3) = histeq(hsvImg(:,:,3));
        % 转回RGB空间
        equalizedImg = hsv2rgb(hsvImg);
    else  % 灰度图像
        equalizedImg = histeq(img);
    end
    
    % 更新处理后图像
    userData.processedImg = equalizedImg;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示处理后的图像
    axes(imgAxes);
    imshow(equalizedImg);
    title('处理后图像', 'Color', [1, 1, 1]);
end

%% --- 摄像头相关函数 ---

% 启动摄像头函数
function startCamera(mainFig, imgAxes)
    % 检查是否已有摄像头对象
    userData = getappdata(mainFig, 'UserData');
    if isfield(userData, 'vid') && isvalid(userData.vid)
        return; % 摄像头已经启动
    end
    
    try
        % 创建视频输入对象
        vid = videoinput('winvideo', 1, 'YUY2_640x480'); % 根据你的摄像头调整格式
        src = getselectedsource(vid);
        
        % 设置摄像头参数
        vid.FramesPerTrigger = Inf;
        vid.ReturnedColorspace = 'rgb';
        
        % 设置预览回调函数
        vid.TimerFcn = {@cameraPreviewCallback, mainFig, imgAxes};
        vid.TimerPeriod = 0.05; % 每秒20帧
        
        % 保存摄像头对象
        userData.vid = vid;
        setappdata(mainFig, 'UserData', userData);
        
        % 开始预览
        start(vid);
        
    catch ME
        errordlg(['无法启动摄像头: ' ME.message], '摄像头错误');
    end
end

% 摄像头预览回调函数
function cameraPreviewCallback(vid, ~, mainFig, imgAxes)
    % 获取最新帧
    frame = getsnapshot(vid);
    
    % 更新用户数据
    userData = getappdata(mainFig, 'UserData');
    userData.originalImg = frame;
    userData.processedImg = frame;
    userData.trueOriginalImg = frame;
    userData.isGrayscale = false;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示图像
    axes(imgAxes);
    imshow(frame);
    title('实时摄像头输入', 'Color', [1, 1, 1]);
end

% 停止摄像头函数
function stopCamera(mainFig)
    userData = getappdata(mainFig, 'UserData');
    if isfield(userData, 'vid') && isvalid(userData.vid)
        stop(userData.vid);
        delete(userData.vid);
        userData = rmfield(userData, 'vid');
        setappdata(mainFig, 'UserData', userData);
    end
end

% 从摄像头捕获图像函数
function captureFromCamera(mainFig, originalImgAxes, processedImgAxes)
    userData = getappdata(mainFig, 'UserData');
    if ~isfield(userData, 'vid') || ~isvalid(userData.vid)
        errordlg('摄像头未启动', '错误');
        return;
    end
    
    % 获取当前帧
    frame = getsnapshot(userData.vid);
    
    % 更新用户数据
    userData.originalImg = frame;
    userData.processedImg = frame;
    userData.trueOriginalImg = frame;
    userData.isGrayscale = false;
    setappdata(mainFig, 'UserData', userData);
    
    % 显示原始图像
    axes(originalImgAxes);
    imshow(frame);
    title('原始图像', 'Color', [1, 1, 1]);
    
    % 显示处理后图像
    axes(processedImgAxes);
    imshow(frame);
    title('待识别图像', 'Color', [1, 1, 1]);
    
    % 重置滑动条
    rotationSlider = findobj(mainFig, 'Style', 'slider', 'Min', -180);
    cropSlider = findobj(mainFig, 'Style', 'slider', 'Min', 0.1);
    rotationText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*°'));
    cropText = findobj(mainFig, 'Style', 'text', 'String', regexptranslate('wildcard', '*%'));
    
    if ~isempty(rotationSlider) && ~isempty(cropSlider)
        set(rotationSlider, 'Value', 0);
        set(cropSlider, 'Value', 1);
        set(rotationText, 'String', '0°');
        set(cropText, 'String', '100%');
    end
end